package app.server.project.main.service.service.cms;

import app.server.project.core.http.CMSLstResp;
import app.server.project.core.websocket.WSMgr;
import app.server.project.main.service.bo.dbquery.QueryActiveParam;
import app.server.project.main.service.bo.dbquery.QueryUserInfoParam;
import app.server.project.main.service.db.dao.cfg.RaceCfgDao;
import app.server.project.main.service.db.dao.statics.StaticsActiveDao;
import app.server.project.main.service.db.entity.statics.StaticsActiveEntity;
import app.server.project.main.service.db.mapper.user.UserInfoMapper;
import app.server.project.main.service.dto.cms.CMSUserInfoDto;
import app.server.project.main.service.dto.cms.OnlineDto;
import app.server.project.main.service.dto.cms.QueryActiveReq;
import app.server.project.main.service.dto.cms.QueryUserInfoReq;
import app.server.project.main.service.service.race.CoinType;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class BusinessService {

    private final static int MAX = 50;

    private final UserInfoMapper userInfoMapper;
    private final RaceCfgDao raceCfgDao;
    private final StaticsActiveDao staticsActiveDao;
    private List<OnlineDto> onlineDtoList = new ArrayList<>();

    /**
     * 查询用户基本信息
     *
     * @param req
     * @return
     */
    public CMSLstResp<CMSUserInfoDto> getAllUserInfo(QueryUserInfoReq req) {
        var aiCoinCfg = this.raceCfgDao.getAiCoin();
        var btcCfg = this.raceCfgDao.getOne(CoinType.BTC_COIN);
        var dbLst = this.userInfoMapper.getAllByParam(Page.of(req.getPageIndex() + 1, req.getPageSize()), QueryUserInfoParam.of(req));
        return CMSLstResp.of(dbLst.getRecords().
                        stream().
                        map(v -> {
                            return CMSUserInfoDto.of(v, aiCoinCfg, btcCfg);
                        }).
                        collect(Collectors.toList()),
                dbLst.getTotal());
    }

    public CMSLstResp<StaticsActiveEntity> getActiveData(QueryActiveReq req) {
        Page<StaticsActiveEntity> page = Page.of(req.getPageIndex(), req.getPageSize());
        var param = new QueryActiveParam();
        BeanUtil.copyProperties(req, param);
        if (param.getEnd() != null) {
            param.setEnd(param.getEnd().plusDays(1));
        }
        var data = this.staticsActiveDao.getAll(page, param);
        return CMSLstResp.of(data.getRecords(), data.getTotal());
    }

    public CMSLstResp<OnlineDto> getOnlineNum() {
        return CMSLstResp.of(this.onlineDtoList, this.onlineDtoList.size());
    }

    @Scheduled(fixedRate = 3 * 1000)
    public void sumOnline() {
        this.onlineDtoList.add(0, OnlineDto.of(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSSXXX"), WSMgr.getOnlineNum(), new Date()));
        if (this.onlineDtoList.size() >= MAX) {
            this.onlineDtoList = this.onlineDtoList.subList(0, MAX);
        }
    }
}
